home *** CD-ROM | disk | FTP | other *** search
- TITLE MSBMKB MS-DOS System EXE to BOO Utility Program
-
- ; (c) 1988 W.C. Parke, WGCP0086@GWUVM
- ;
- ; This program converts an EXE to a BOO file
- ;
- ; BOO files are ASCII files constructed from binary files for the purpose
- ; of transferring the files over networks or tape which do not accept binary.
- ; The translation is by the following algorithm (by Bill Catchings):
- ; 1. The name of the file is placed on the first line, in plain text,
- ; followed by CR,LF.
- ; 2. If a series of nulls occurs, a '~' (7EH) is used followed by
- ; an byte number for the null count from 2 to 78 plus '0' bias.
- ; 3. Three byte sequences are coded as 4 bytes, taking lower 6 bits from
- ; each byte and adding a '0' bias.
- ; 4. Carriage return/linefeeds are inserted to make lines breaks
- ; at column 76 unless a split of 4 byte code would occur. If so,
- ; line ends at column 74.
- ;
- ; MSBMKB compiled with MASM 5.10. Use LINK and EXE2BIN to make COM file.
- ;
- ; May be used with any file on any MS-DOS path.
- ; BOO file is created in current directory.
- ;
- ; MSBMKB uses the file name on the first line of the BOO file
- ; for its output file.
-
- LF EQU 0AH
- CR EQU 0DH
- BUFSIZ EQU 6000H
-
- CODE SEGMENT
- ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
-
- ORG 100H
-
- START: JMP BOO
- FHAND1 DW 0
- DW 0
- FNAM1 DB 80 DUP(0)
- FHAND2 DW 0
- DW 0
- FNAM2 DB 16 DUP(0)
- DW 0
- FNAMT DB 16 DUP(0)
- INVOC DB CR,LF,'MSMKB Version 1.1'
- DB CR,LF,'EXE to BOO file converter.'
- DB CR,LF,'(c) 1988 W.C. Parke',CR,LF,CR,LF,'$'
- DHPERR DB 'Syntax:',CR,LF,LF
- DB ' MSBMKB filename',CR,LF,CR,LF,'$'
- DCONV DB 'Converting $'
- DTO DB ' to $'
- DDOT DB ' ... $'
- DEXIST DB ' already exists. Overwrite it? $'
- DERROR DB CR,LF,'Error in file $'
- DOPERR DB 'open$'
- DCRERR DB 'creation$'
- DCLERR DB 'close$'
- DRDERR DB 'read$'
- DWRERR DB 'write$'
- DERRF DB '.',CR,LF,'$'
- FBOO DB '.BOO',0,0
- DONE DB CR,LF,'Done. ',CR,LF,'$'
- FEOF DB 0
- FEND DW 0
- FEND2 DW 0
-
- BOO: MOV AH,9
- MOV DX,OFFSET INVOC
- INT 21H ; give our invocation
- MOV SI,80H
- LODSB
- XOR AH,AH
- AND AX,AX
- JNZ BOF ; got command line tail
- JMP ABORTHP ; give help screen
- BOF: MOV DI,OFFSET FNAM1
- INC AX
- MOV CX,AX
- BO0: LODSB ; get byte of command line tail
- CMP AL,CR ; check for cr termination
- JZ BO1
- CMP AL,20H
- JZ BOL ; check for spaces
- CMP AL,'a'
- JC BOLL
- AND AL,5FH
- BOLL: STOSB ; save in file name buffer
- BOL: LOOP BO0 ; continue
- BO1: XOR AL,AL
- STOSB ; make asciiz string
- DEC DI ; point to 0
- MOV AX,OFFSET FNAM1
- MOV CX,DI
- SUB CX,AX
- MOV FEND,CX ; size of file and path name to 0
- INC CX
- INC CX
- STD
- MOV AL,'\'
- REPNZ SCASB
- CLD
- INC DI
- INC DI ; pointer to fnam1 without path
- MOV SI,DI
- MOV DI,OFFSET FNAM2
- XOR CX,CX
- BON: LODSB
- INC CX
- AND AL,AL
- STOSB ; move copy to fnam2
- JZ BOM
- JMP SHORT BON
- BOM: DEC CX
- MOV FEND2,CX ; size of fnam2
- MOV SI,OFFSET FNAM2
- MOV DI,OFFSET FNAMT
- MOV CX,8
- REP MOVSW ; copy file name for header of BOO file
- MOV DX,OFFSET FNAM1
- MOV AH,3DH ; open file 1
- INT 21H
- JNC BO2
- JMP ABORTOP ; give error on open message
- BO2: MOV FHAND1,AX ; save handle
- MOV DI,OFFSET FNAM2
- MOV CX,FEND2
- ADD DI,CX
- PUSH DI ; save ptr to 0
- STD
- INC CX
- MOV AL,'.'
- REPNZ SCASB ; look for '.' in string from rear
- CLD
- JCXZ BO3 ; not found
- INC DI ; point to '.'
- POP AX ; drop old 0 pointer
- PUSH DI ; use new pointer
- BO3: POP SI ; pointer to extension in FNAM1
- MOV DI,SI
- MOV SI,OFFSET FBOO
- MOV CX,3
- REP MOVSW ; add BOO extension to fnam2
- MOV DX,OFFSET FNAM2
- XOR CX,CX
- MOV AH,4EH
- INT 21H ; search file
- JC BOZ
- MOV SI,OFFSET FNAM2
- CALL SHOW
- MOV AH,9
- MOV DX,OFFSET DEXIST ; already exists
- INT 21H
- MOV AX,0C01H
- INT 21H ; look for user response
- PUSH AX
- MOV AH,2
- MOV DL,CR
- INT 21H
- MOV DL,LF
- INT 21H
- POP AX
- AND AL,5FH
- CMP AL,'Y'
- JZ BOZ ; got overwrite permission
- JMP EXIT
- BOZ: MOV DX,OFFSET FNAM2
- MOV AH,3CH
- XOR CX,CX
- INT 21H ; create output file
- JC ABORTCR
- MOV FHAND2,AX ; save handle
- MOV AH,9
- MOV DX,OFFSET DCONV
- INT 21H ; say converting
- MOV SI,OFFSET FNAM1
- CALL SHOW
- MOV AH,9
- MOV DX,OFFSET DTO
- INT 21H
- MOV SI,OFFSET FNAM2
- CALL SHOW
- MOV AH,9
- MOV DX,OFFSET DDOT
- INT 21H
- MOV SI,OFFSET FNAMT
- XOR AX,AX
- MOV BP,AX ; line column count
- MOV CNT1,AX
- MOV CNT2,AX ; zero buffer counts
- MOV DI,OFFSET FBUF2
- MOV CX,16 ; do no more than 16
- BO4: LODSB
- AND AL,AL ; end of asciiz string
- JZ BO5
- SUB AL,'0' ; anticipate bias
- CALL OUTB ; send to file2 buffer
- LOOP BO4
- BO5: CALL OUTCR ; send lf,cr
- MOV SI,OFFSET FBUF1
- JMP NEXT ; start exe file conversion
- ABORTOP:
- MOV DX,OFFSET DOPERR ; file open error
- MOV AL,2
- JMP ABORT
- ABORTCR:
- MOV DX,OFFSET DCRERR ; file creation error
- MOV AL,3
- JMP ABORT
- ABORTCL:
- MOV DX,OFFSET DCLERR ; file close error
- MOV AL,7
- JMP ABORT
- PUBLIC NULLS
- NUL1: MOV BL,AL ; put byte-2 after null
- XOR BH,BH ; put null for byte-1
- JMP SHORT NEX3 ; process next byte for byte-3
- NULLS: CALL GETB ; process multiple nulls
- AND AL,AL
- JNZ NUL1 ; only one null
- CMP BP,75 ; columns count - 2
- JC NULG
- CALL OUTCR
- NULG: MOV AL,'~'-'0' ; ascii null flag
- CALL OUTB
- MOV CX,77 ; lowest count is 2
- MOV BX,78 ; largest count allowed
- NULSN: CALL GETB
- AND AL,AL
- LOOPZ NULSN
- NULF: PUSH AX ; save non-null for byte-1
- SUB BX,CX ; find null count
- MOV AX,BX
- CALL OUTB
- POP AX
- JMP SHORT NEX1
- PUBLIC NEXT
- NEXT: CALL GETB ; get byte-1 xxxxxxxx
- NEX1: AND AL,AL
- JZ NULLS ; got a null
- MOV AH,AL
- CALL GETB ; get byte-2 yyyyyyyy
- MOV BX,AX
- NEX3: CALL GETB ; get byte-3 zzzzzzzz
- MOV CH,AL
- MOV AX,BX
- SHR AX,1
- SHR AX,1
- XCHG AH,AL
- CMP BP,73 ; columns count - 4
- JC NEXG
- CALL OUTCR
- NEXG: CALL OUTB ; send 00xxxxxx
- XCHG AL,AH
- SHR AL,1
- SHR AL,1
- CALL OUTB ; send 00xxyyyy
- MOV AH,BL
- AND AH,0FH
- MOV AL,CH
- SHL AX,1
- SHL AX,1
- XCHG AH,AL
- CALL OUTB ; send 00yyyyzz
- MOV AL,AH
- SHR AL,1
- SHR AL,1
- CALL OUTB ; send 00zzzzzz, fourth of quarted
- JMP NEXT
-
- PUBLIC GETB
- CNT1 DW 0 ; byte count in buffer 1
- EXTRA DB 3 ; extra byte count to finish ascii quartet
- GETB: CMP WORD PTR CNT1,0
- JZ GETBF ; get more from file
- GETBG: LODSB
- DEC WORD PTR CNT1 ; on less in buffer
- RET
- GETBF: CALL GETMF ; file get
- JNC GETBG ; got more file bytes
- TEST BYTE PTR FEOF,0FFH
- JZ GETBEC ; error if not end of file
- DEC EXTRA
- CMP EXTRA,0 ; any extra bytes to add?
- JZ FIN ; no
- MOV AL,90H ; add extra 'nop' to file
- RET
- GETBEC: POP AX ; drop return address
- JMP ABORTWR
- PUBLIC FIN
- FIN: POP AX ; drop return address
- CALL OUTLST ; save last of converted file
- JNC EXIT
- JMP ABORTCL ; close error
- EXIT: MOV AH,9
- MOV DX,OFFSET DONE
- INT 21H
- MOV AX,4C00H
- INT 21H ; good exit
-
- GETMFF: STC ; got eof
- RET
- GETMF: TEST BYTE PTR FEOF,0FFH
- JNZ GETMFF
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- MOV BX,FHAND1
- MOV DX,OFFSET FBUF1
- MOV AH,3FH
- MOV CX,BUFSIZ ; file buffer size
- INT 21H ; get bytes
- MOV SI,OFFSET FBUF1
- POP DX
- POP CX
- POP BX
- JC GETBC ; read error
- MOV CNT1,AX ; new byte count
- AND AX,AX
- JZ GETBE ; no more bytes
- GETBC: POP AX
- RET
- GETBE: INC BYTE PTR FEOF ; set eof
- POP AX
- STC
- RET
-
- OUTCR: XOR BP,BP ; new column
- PUSH AX
- MOV AL,0DDH ; cr-'0'
- CALL OUTB ; send cr
- MOV AL,0DAH ; lf-'0'
- CALL OUTB ; send lf
- POP AX
- XOR BP,BP ; reset column position
- RET
-
- PUBLIC OUTB
- CNT2 DW 0 ; buffer 2 character count
- OUTBB: CALL OUTBF ; write buffer contents
- JC OUTBCA ; write error
- JMP SHORT OUTBS ; start filling new buffer
- OUTB: CMP CNT2,BUFSIZ ; any space in buffer?
- JNC OUTBB ; no, write buffer
- OUTBS: ADD AL,'0' ; add bias to byte
- STOSB ; save character
- INC BP ; increment column position
- INC WORD PTR CNT2 ; and characters in buffer
- CLC
- RET
- OUTBCA: POP AX
- JMP ABORTWR ; write error
-
- OUTBF: PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- MOV BX,WORD PTR FHAND2
- MOV AH,40H
- MOV DX,OFFSET FBUF2
- MOV CX,BUFSIZ
- INT 21H ; write file 2 buffer
- POP DX
- POP CX
- POP BX
- JC OUTBC ; write error
- CMP AX,BUFSIZ
- JNZ OUTBC ; carry set if incomplete write
- MOV WORD PTR CNT2,0 ; reset character count
- MOV DI,OFFSET FBUF2 ; and buffer pointer
- OUTBC: POP AX
- RET
- OUTLST: CALL OUTCR ; send final cr,lf
- MOV BX,WORD PTR FHAND2
- MOV AH,40H
- MOV DX,OFFSET FBUF2
- MOV CX,CNT2
- INT 21H ; write
- MOV AH,3EH
- INT 21H ; and close
- RET
- ABORTHP:
- MOV DX,OFFSET DHPERR
- MOV AH,9
- INT 21H ; show help screen
- MOV AX,4C01H
- INT 21H
- ABORTRD:
- MOV DX,OFFSET DRDERR ; read error
- MOV AL,4
- JMP SHORT ABORT
- ABORTWR:
- MOV DX,OFFSET DWRERR ; write error
- MOV AL,6
- ABORT: CALL ABERR ; error in file ...
- PUSH AX
- MOV AH,9
- INT 21H ; ...(error type)
- MOV DX,OFFSET DERRF ; period
- INT 21H
- POP AX ; errorlevel in AL
- MOV AH,4CH
- INT 21H
- ABERR: PUSH AX
- PUSH DX
- MOV DX,OFFSET DERROR
- MOV AH,9
- INT 21H ; show error in file
- POP DX
- POP AX
- RET
- EVEN
- SHOW: MOV AH,2 ; show asciiz string
- SHOM: LODSB
- AND AL,AL
- JZ SHOE
- MOV DL,AL
- INT 21H
- JMP SHORT SHOM
- SHOE: RET
-
- FBUF1 EQU $
- FBUF2 EQU $+BUFSIZ
-
- CODE ENDS
-
- END START
-